package com.fs.base.utils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import lombok.Getter;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fs.base.jpa.interf.QueryOpt;
import com.fs.base.jpa.interf.QueryOpt.Operator;
import com.fs.base.jpa.specification.Criteria;
import com.fs.base.jpa.vo.LogicalExpression;
import com.fs.base.jpa.vo.QueryExpression;
import com.fs.base.param.SysConstant;
import com.fs.base.pojo.User;
import com.fs.base.vo.LoginUser;
import com.fs.jzzn.param.QueryMap;

/**
 * @author TiddlerCJ
 * @desc 系统应用工具
 */
@Component
public class ApplicationUtils {

	@Getter
	private static ApplicationContext ctx;

	@Autowired
	public void setCtx(ApplicationContext ctx) {
		ApplicationUtils.ctx = ctx;
	}

	/**
	 * 获取当前Request
	 * @return
	 */
	public static HttpServletRequest getRequest() {
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
        return requestAttributes.getRequest();
    }

	/**
	 * 获取当前Session
	 * @return
	 */
	public static HttpSession getSession() {
        return getRequest().getSession(true);
    }

	/**
	 * 获取springBean对象
	 * @param beanName
	 * @return
	 */
	public static Object getBean(String beanName) {
		return ctx.getBean(beanName);
	}

	/**
	 * 获取所有请求参数及参数值
	 * @return
	 */
	public static Map<String, Object> getRequestDatas(String... searchType) {
		Map<String, Object>  data = new HashMap<String, Object>();
		HttpServletRequest request = getRequest();
		Map<String, String[]> map = request.getParameterMap();
		Integer len = 0;
		Object value = null;
		for(String key : map.keySet()){
			String[] vArray = map.get(key);
			len = vArray.length;
			if(len==1){
				value = vArray[0];
				if(QueryMap.queryKeyMaps.containsKey(value)){
					value = QueryMap.queryKeyMaps.get(value);
				}
				data.put(key, value);
				
				if(searchType!=null && searchType.length>0){
					data.put(key.concat("_searchType"),searchType[0]);
				}
			}else if(len>1){
				data.put(key, vArray);
			}else{
				continue;
			}
		}
		return data;
	}
	
	/**
	 * request数据转java对象
	 * @param class1
	 * @return
	 */
	public static Object requestData2Bean(Class<?> class1,boolean isSave) {
		Map<String, Object> map = getRequestDatas();
		if(isSave){
			/*自动设置createId*/
			map.put("createrId", userId());
		}
		String json = JSON.toJSONString(map);
		return JSON.parseObject(json, class1);
	}

	public static Boolean isSuperAdmin(){
		boolean flag = false;
		User user = User();
		if(user!=null && SysConstant.SUPER_ADMIN_ACOUNT.equals(user.getAccount())){
			flag = true;
		}
		return flag;
	}

	/**
	 * 获取session用户信息
	 * @return
	 */
	public static LoginUser LoginUser (){
		HttpSession session = getRequest().getSession();
		LoginUser vo = (LoginUser) session.getAttribute(SysConstant.SESSION_CONSOLE_USER);
		return vo;
	}
	
	/**
	 * 获取后端登录用户
	 * @return
	 */
	public static User User (){
		User user = null;
		LoginUser vo = LoginUser();
		if(vo!=null) user = vo.getUser();
		return user;
	}

	public static String userId(){
		String userId = null;
		User user = User();
		if(user!=null){
			userId = user.getId();
		}
		return userId;
	}
	/**
	 *获取前端网站登录用户
	 */
	public static User getWebUser (){
		HttpSession session = getRequest().getSession();
		User vo = (User) session.getAttribute(SysConstant.SESSION_WEB_USER);
		return vo;
	}

	 /** 获取url地址 */
    public static String getCurUrl() {
    	HttpServletRequest request = getRequest();
        String url = request.getScheme()+"://"+ request.getServerName()+":"+request.getServerPort();
        return url;
    }

	/**
	 * 获取当前登录用户菜单按钮信息
	 * @return
	 */
	public static JSONObject getMenuMotions (){
		HttpSession session = getRequest().getSession();
		JSONObject vo = (JSONObject) session.getAttribute(SysConstant.SESSION_CONSOLE_MENU_MOTION);
		return vo;
	}

	public static String getRemoteHost(){
		HttpServletRequest request = getRequest();
	    String ip = request.getHeader("x-forwarded-for");
	    if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)){
	        ip = request.getHeader("Proxy-Client-IP");
	    }
	    if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)){
	        ip = request.getHeader("WL-Proxy-Client-IP");
	    }
	    if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)){
	        ip = request.getRemoteAddr();
	    }
	    return ip.equals("0:0:0:0:0:0:0:1")?"127.0.0.1":ip;
	}

	/**
	 * 获取ContextPath
	 */
	public static String getContextPath() {
		return getContextPath(getRequest());
	}

	/**
	 * 获取ContextPath
	 */
	public static String getContextPath(HttpServletRequest request) {
		if (null == request) request = getRequest();
		String path = null != request ? request.getContextPath() : "";
		if ("/".equals(path)) path = "";
		return path;
	}
	
	
	/**
	 * 组织数据过滤
	 * 非管理员账号登录时启用组织机构代码过滤
	 */
	public static void addDataFilter(Criteria<Object> criteria){
		/*
		 * 数据权限过滤
		 */
		Map<String, Integer> accessMap = ApplicationUtils.LoginUser().getMenuAccessMap();
		String accessMenuId = ApplicationUtils.getRequest().getParameter("accessMenuId");
		String className = ApplicationUtils.getRequest().getParameter("className");
		
		if(StringUtils.isBlank(className) 
				|| StringUtils.isBlank(accessMenuId)
				|| CollectionUtils.isEmpty(accessMap)
				|| !accessMap.containsKey(accessMenuId) ) return;
		
		Integer accessValue = accessMap.get(accessMenuId);
		Set<String> filedSet = ModleTools.getFieldSetByClassName(className);
		String orgNo = ApplicationUtils.User().getOrgNo();
		switch (accessValue) {
			case 4:
				//所有数据权限，不做处理
				break;
			case 1:
				//自己
				if(filedSet.contains("createrId")){
					criteria.addEq("createrId", ApplicationUtils.userId());
				}
				break;
			case 2:
				//所属部门
				if(filedSet.contains("orgNo") && StringUtils.isNotBlank(orgNo)){
					if(filedSet.contains("createrId")){
						List<QueryOpt> expressions = new ArrayList<QueryOpt>();
						expressions.add(new QueryExpression("orgNo", orgNo, Operator.EQ));
						expressions.add(new QueryExpression("createrId", ApplicationUtils.userId(), Operator.EQ));
						LogicalExpression logicalExpression = new LogicalExpression(expressions.toArray(new QueryOpt[2]), Operator.OR);
						criteria.addOr(logicalExpression);
					}else{
						criteria.addEq("orgNo", orgNo);
					}
				}else{
					criteria.addEq("createrId", ApplicationUtils.userId());
				}
				break;
			case 3:
				//所属部门级子部门
				if(filedSet.contains("orgNo") && StringUtils.isNotBlank(orgNo)){
					if(filedSet.contains("createrId")){
						List<QueryOpt> expressions = new ArrayList<QueryOpt>();
						expressions.add(new QueryExpression("orgNo", orgNo, Operator.LIKE));
						expressions.add(new QueryExpression("createrId", ApplicationUtils.userId(), Operator.EQ));
						LogicalExpression logicalExpression = new LogicalExpression(expressions.toArray(new QueryOpt[2]), Operator.OR);
						criteria.addOr(logicalExpression);
					}else{
						criteria.addEq("orgNo", orgNo);
					}
				}else{
					criteria.addEq("createrId", ApplicationUtils.userId());
				}
				break;
			case 5:
				orgNo += (","+ ApplicationUtils.User().getDept());
				//所属项目部业务数据权限
				if(filedSet.contains("orgNo") && StringUtils.isNotBlank(orgNo)){
					int optLen = 0;
					List<QueryOpt> expressions = new ArrayList<QueryOpt>();
					Set<String> valueSet = new HashSet<String>();
					String[] values = orgNo.split(",");
					for(String item: values){
						valueSet.add(item);
					}
					for(String no: valueSet){
						expressions.add(new QueryExpression("orgNo", no, Operator.EQ));
					}
					optLen = valueSet.size();
					if(filedSet.contains("createrId")){
						expressions.add(new QueryExpression("createrId", ApplicationUtils.userId(), Operator.EQ));
						optLen ++ ;
					}
					LogicalExpression logicalExpression = new LogicalExpression(expressions.toArray(new QueryOpt[optLen]), Operator.OR);
					criteria.addOr(logicalExpression);
				}else{
					criteria.addEq("createrId", ApplicationUtils.userId());
				}
				break;
			default:
				/*
				 * 默认以当前用户id做过滤
				 */
				if(filedSet.contains("createrId")){
					criteria.addEq("createrId", ApplicationUtils.userId());
				}
				break;
		}
	}

}
